/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.java.spring.xml;

import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.env.MissingRequiredPropertiesException;
import org.springframework.lang.Nullable;

/**
 * Configuration interface to be implemented by most if not all {@link PropertyResolver}
 * types. Provides facilities for accessing and customizing the
 * {@link org.springframework.core.convert.ConversionService ConversionService}
 * used when converting property values from one type to another.
 *
 * @author Chris Beams
 * @since 3.1
 */
public interface ConfigurablePropertyResolver extends PropertyResolver {

    /**
     * 返回执行类型转换时使用的 ConfigurableConversionService
     * Return the {@link ConfigurableConversionService} used when performing type
     * conversions on properties.
     * <p>The configurable nature of the returned conversion service allows for
     * the convenient addition and removal of individual {@code Converter} instances:
     * <pre class="code">
     * ConfigurableConversionService cs = env.getConversionService();
     * cs.addConverter(new FooConverter());
     * </pre>
     *
     * @see PropertyResolver#getProperty(String, Class)
     * @see org.springframework.core.convert.converter.ConverterRegistry#addConverter
     */
    ConfigurableConversionService getConversionService();

    /**
     * 设置 ConfigurableConversionService
     * Set the {@link ConfigurableConversionService} to be used when performing type
     * conversions on properties.
     * <p><strong>Note:</strong> as an alternative to fully replacing the
     * {@code ConversionService}, consider adding or removing individual
     * {@code Converter} instances by drilling into {@link #getConversionService()}
     * and calling methods such as {@code #addConverter}.
     *
     * @see PropertyResolver#getProperty(String, Class)
     * @see #getConversionService()
     * @see org.springframework.core.convert.converter.ConverterRegistry#addConverter
     */
    void setConversionService(ConfigurableConversionService conversionService);

    /**
     * 设置占位符前缀
     * Set the prefix that placeholders replaced by this resolver must begin with.
     */
    void setPlaceholderPrefix(String placeholderPrefix);

    /**
     * 设置占位符后缀
     * Set the suffix that placeholders replaced by this resolver must end with.
     */
    void setPlaceholderSuffix(String placeholderSuffix);

    /**
     * 设置占位符与默认值之间的分隔符
     * Specify the separating character between the placeholders replaced by this
     * resolver and their associated default value, or {@code null} if no such
     * special character should be processed as a value separator.
     */
    void setValueSeparator(@Nullable String valueSeparator);

    /**
     * 设置当遇到嵌套在给定属性值内的不可解析的占位符时是否抛出异常
     * 当属性值包含不可解析的占位符时，getProperty(String)及其变体的实现必须检查此处设置的值以确定正确的行为。
     * Set whether to throw an exception when encountering an unresolvable placeholder
     * nested within the value of a given property. A {@code false} value indicates strict
     * resolution, i.e. that an exception will be thrown. A {@code true} value indicates
     * that unresolvable nested placeholders should be passed through in their unresolved
     * ${...} form.
     * <p>Implementations of {@link #getProperty(String)} and its variants must inspect
     * the value set here to determine correct behavior when property values contain
     * unresolvable placeholders.
     *
     * @since 3.2
     */
    void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders);

    /**
     * 指定必须存在哪些属性，以便由validateRequiredProperties（）验证
     * Specify which properties must be present, to be verified by
     * {@link #validateRequiredProperties()}.
     */
    void setRequiredProperties(String... requiredProperties);

    /**
     * 验证setRequiredProperties指定的每个属性是否存在并解析为非null值
     * Validate that each of the properties specified by
     * {@link #setRequiredProperties} is present and resolves to a
     * non-{@code null} value.
     *
     * @throws MissingRequiredPropertiesException if any of the required
     *                                            properties are not resolvable.
     */
    void validateRequiredProperties() throws MissingRequiredPropertiesException;

}
